package cn.tangjiabao.halodb.spring.dao.impl;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.dbutils.handlers.ScalarHandler;

import cn.tangjiabao.halodb.core.AbstractHaloDao;
import cn.tangjiabao.halodb.core.map.HaloGetMap;
import cn.tangjiabao.halodb.dbutils.handlers.HaloBeanHandler;
import cn.tangjiabao.halodb.dbutils.handlers.HaloBeanListHandler;
import cn.tangjiabao.halodb.dbutils.handlers.HaloGetMapHandler;
import cn.tangjiabao.halodb.dbutils.handlers.HaloGetMapListHandler;
import cn.tangjiabao.halodb.spring.dao.IHaloDao;
import cn.tangjiabao.halodb.spring.dao.IHaloViewDao;
import cn.tangjiabao.halodb.spring.template.JdbcTemplate;
import cn.tangjiabao.halodb.utils.convert.HConvertUtils;
import cn.tangjiabao.halodb.utils.logger.HLogUtils;
import cn.tangjiabao.halodb.utils.sql.HSQLFormatter;
import cn.tangjiabao.halodb.utils.string.HStringUtils;

/**
 * 依赖DbUtils的操作的抽象类
 * 
 * @author von_change@163.com
 * @date 2015-6-14 下午10:15:38
 * @param <T>
 */
public abstract class HaloDaoImpl<T> extends AbstractHaloDao<T> implements IHaloDao<T>, IHaloViewDao<T> {

	@Resource
	private JdbcTemplate jdbcTemplate;

	protected void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	private String generateMyCountSql(String sql) {
		return HStringUtils.format("select count(1) from ({0}) temp ", sql);
	}

	protected long countMySqlResult(String sql, Object[] params) {
		String countSql = generateMyCountSql(sql);
		Object result = findBy(countSql, 1, params);
		return HConvertUtils.toLong(result);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private Object findBy(String sql, int columnIndex, Object[] params) {
		Object object = jdbcTemplate.query(sql, new ScalarHandler(columnIndex), params);
		return object;
	}

	protected List<T> queryList(String sql, Object[] params, Map<String, String> aliasMap) {
		logger.debug(HLogUtils.format("生成的sql为:", HSQLFormatter.format(sql)));
		logger.debug(HLogUtils.attr("prams:", params));
		List<T> list =jdbcTemplate.query(sql, new HaloBeanListHandler<T>(getEntityType(), aliasMap), params);
		return list;
	}

	protected T queryOne(String sql, Object[] params, Map<String, String> aliasMap) {
		logger.debug(HLogUtils.format("生成的sql为:", HSQLFormatter.format(sql)));
		logger.debug(HLogUtils.attr("prams:", params));
		T bean = jdbcTemplate.query(sql, new HaloBeanHandler<T>(getEntityType(), aliasMap), params);// conn,
		return bean;
	}

	protected HaloGetMap queryUnique(String sql, Object[] params, Map<String, String> aliasMap) {
		logger.debug(HLogUtils.format("生成的sql为:", HSQLFormatter.format(sql)));
		logger.debug(HLogUtils.attr("prams:", params));
		HaloGetMap map  = jdbcTemplate.query(sql, new HaloGetMapHandler(), params);
		return map;
	}

	protected Object insert(String sql, Object[] params) {
		logger.debug(HLogUtils.format("生成的sql为:", HSQLFormatter.format(sql)));
		logger.debug(HLogUtils.attr("prams:", params));
		Object object  = jdbcTemplate.insert(sql, new ScalarHandler<Object>(), params);
		return object;
	}

	protected int delete(String sql, Object[] params) {
		return update(sql, params);
	}

	protected int update(String sql, Object[] params) {
		logger.debug(HLogUtils.format("生成的sql为:", HSQLFormatter.format(sql)));
		logger.debug(HLogUtils.attr("prams:", params));
		int affectedRows  = jdbcTemplate.update( sql, params);	
		return affectedRows;
	}

	protected HaloGetMap callProc(String sql, Object[] params) {
		logger.debug(HLogUtils.format("生成的sql为:", HSQLFormatter.format(sql)));
		logger.debug(HLogUtils.attr("prams:", params));
		HaloGetMap map = jdbcTemplate.queryProc(sql, new HaloGetMapHandler(), params);		
		return map;
	}

	protected List<HaloGetMap> callProcList(String sql, Object[] params) {
		logger.debug(HLogUtils.format("生成的sql为:", HSQLFormatter.format(sql)));
		logger.debug(HLogUtils.attr("prams:", params));
		List<HaloGetMap> mapList  = jdbcTemplate.queryProc(sql, new HaloGetMapListHandler(), params);
		return mapList;
	}

}
